import { QuadTree } from "../../cccframework/Common/Components/QuadTree";
import { SceneBase } from "../../cccframework/Common/Components/SceneBase";




const { ccclass, property } = cc._decorator;

@ccclass
export default class quadTreeScene extends SceneBase {

    @property(cc.Label)
    countLabel: cc.Label = null;

    qtree: QuadTree = null;
    a: cc.Node = null;
    mainNode: cc.Node = null;
    ctx: cc.Graphics = null;
    _allItems: Array<cc.Node> = [];
    get allItems(): cc.Node[] {
        this._allItems = this._allItems.filter((v)=>{
            return v && v.isValid;
        })
        return this._allItems;
    }
    set allItems(v: cc.Node[]) {
        this._allItems = v;
    }


    onLoad() {
        super.onLoad && super.onLoad()
        this.a = cc.find('singleColor');
        this.mainNode = cc.find('Canvas/mainNode');
        this.qtree = new QuadTree(new cc.Rect(0, 0, cc.winSize.width * 0.8, cc.winSize.height), 7, 4, 0)
        cc.find('Canvas').on(cc.Node.EventType.TOUCH_START, this.touchMove, this);
        cc.find('Canvas').on(cc.Node.EventType.TOUCH_MOVE, this.touchMove, this);
        if (!this.ctx) {
            let ctxNode = new cc.Node('ctxNode');
            ctxNode.parent = cc.director.getScene();
            let ctx = ctxNode.addComponent(cc.Graphics);
            ctx.lineWidth = 4;
            ctx.strokeColor = cc.color(255, 0, 0)
            this.ctx = ctx;
        }

    }

    touchMove(touch) {
        this.mainNode.position = this.mainNode.parent.convertToNodeSpaceAR(touch.getLocation())
    }

    addTenSmallNode() {
        for (let i = 0; i < 10; i++) {
            this.addSmallNode();
        }
    }

    addSmallNode() {
        let node = cc.instantiate(this.a);
        node.parent = cc.find('Canvas');
        node.setContentSize(
            10 + Math.random() * 30,
            10 + Math.random() * 30,
        )
        node.position = cc.v2(
            Math.random() * cc.winSize.width * 0.8 - cc.winSize.width / 2,
            Math.random() * cc.winSize.height * 0.8 - cc.winSize.height / 2,
        )
        this.qtree.insert(node);
        this.allItems.push(node);
        if (this.isDynamic) {
            this.moveTo(node);
        }
    }

    addBigNode() {
        let node = cc.instantiate(this.a);
        node.parent = cc.find('Canvas');
        node.setContentSize(
            50 + Math.random() * 100,
            50 + Math.random() * 100,
        )
        node.position = cc.v2(
            Math.random() * cc.winSize.width * 0.8 - cc.winSize.width / 2,
            Math.random() * cc.winSize.height * 0.8 - cc.winSize.height / 2,
        )
        this.qtree.insert(node);
        this.allItems.push(node);
        if (this.isDynamic) {
            this.moveTo(node);
        }
    }

    isDynamic: boolean = false;
    switchState() {
        this.isDynamic = !this.isDynamic;
        if (this.isDynamic) {
            this.nodeMove();
        } else {
            this.nodeStop();
        }
    }

    moveTo(item) {
        let rdmPos = cc.v2(
            Math.random() * cc.winSize.width * 0.8 - cc.winSize.width / 2,
            Math.random() * cc.winSize.height * 0.8 - cc.winSize.height / 2,
        )
        let dist = rdmPos.sub(item.position).mag();
        let time = dist / 60;
        item['moveTween'] = cc.tween(item)
            .to(time, { position: rdmPos })
            .call(() => {
                if (this.isDynamic) {
                    this.moveTo(item);
                }
            })
            .start();
    }

    nodeMove() {
        if (this.allItems.length) {
            for (let i = 0; i < this.allItems.length; i++) {
                let item = this.allItems[i];
                this.moveTo(item);
            }
        }
    }

    nodeStop() {
        if (this.allItems.length) {
            for (let i = 0; i < this.allItems.length; i++) {
                let item = this.allItems[i];
                if (item['moveTween']) {
                    item['moveTween'].stop();
                }
            }
        }
    }

    update(dt) {
        let allItems = this.allItems;
        let elements = this.qtree.retrieve(this.mainNode.getBoundingBoxToWorld());
        // console.log('elements', elements && elements.length)
        this.countLabel.string =
            `
需要检测 ：${elements.length}个
共 ：${allItems.length}个
占比 ：${~~((elements.length / allItems.length) * 100)} %
        `;
        if (allItems.length) {
            for (let i of allItems) {
                i.color = cc.color(255, 255, 255);
                i.opacity = 180;
            }
        }
        let wRect = this.mainNode.getBoundingBoxToWorld()
        for (let i of elements) {
            i.color = cc.color(0, 255, 0);
            i.opacity = 180;
            if (wRect.intersects(i.getBoundingBoxToWorld())) {
                // console.log('碰撞了，删除')
                this.qtree.delete(i);
                i.color = cc.color(255, 0, 0);
                i.destroy();
            }
        }


        if (this.qtree) {
            this.qtree.refresh(this.qtree);
            if (this.ctx) {
                this.ctx.clear();
                let nodes = this.qtree.getAllNodes();
                for (let i = 0; i < nodes.length; i++) {
                    this.ctx.rect(nodes[i].rect.x, nodes[i].rect.y, nodes[i].rect.width, nodes[i].rect.height);
                }
                this.ctx.stroke();
            }
        }
    }
}
